/* -----------------------------------------------------------------------
 * Demonstration of how to write unit tests for dominion-base
 * Include the following lines in your makefile:
 *
 * unittest2: unittest2.c dominion.o rngs.o
 *      gcc -o testUpdateCoins -g  unittest2.c dominion.o rngs.o $(CFLAGS)
 * -----------------------------------------------------------------------
 */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <time.h>
#include "rngs.h"
int getPlayerTotal(struct gameState * state, int playerNumber);
int doesPlayerHaveCopper(struct gameState * state, int playerNumber);
int main() {
	//testing cutpurse card
	struct gameState G;
	int numPlayer = 3;//this card effects all players, so making 3 players will give better test
	int seed = 2;
	int player = 0;//just player 0 for now
	int k[10] = {adventurer, council_room, feast, gardens, mine
		, remodel, smithy, village, baron, great_hall};
	
	
	
//case cutpurse:
//	
//	updateCoins(currentPlayer, state, 2);
//	for (i = 0; i < state->numPlayers; i++)
//	{
//	  if (i != currentPlayer)
//		{
//			for (j = 0; j < state->handCount[i]; j++)
//			{
//				if (state->hand[i][j] == copper)
//		    {
//		      discardCard(j, i, state, 0);
//		      break;
//		    }
//				if (j == state->handCount[i])
//		    {
//		      for (k = 0; k < state->handCount[i]; k++)
//					{
//						if (DEBUG)
//							printf("Player %d reveals card number %d\n", i, state->hand[i][k]);
//					}	
//		      break;
//		    }		
//			}
//			
//		}
//		
//	}				
//	
//	//discard played card from hand
//	discardCard(handPos, currentPlayer, state, 0);			
	
//	return 0;
	
	
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////
	initializeGame(numPlayer, k, seed, &G); // 
	int coin_bonus=0;
	int startingDeckCount = G.deckCount[player];
	int startingHandCount = G.handCount[player];
	int startingActionsCount = G.numActions;
	int startingCoinCount = G.coins; //this gets updated each turn, so not associated to a particular player
	
	//set all of the cards in each person's hand to copper
	int x;
	int playerThreeCoins = 0;
	int playerTwoCoins = 0;
	for (x=0; x<5; x++) {
		G.hand[player+1][x] = copper;
		G.hand[player+2][x] = copper;
		G.handCount[player+1] +=1;
		G.handCount[player+2] +=1;

	}
	
	int handPos = 0;
	
	//this card should add 2 coins to the gamestate during the turn. Also, it should remove one copper from any other player that has at least one copper.
	// Should be fun to test
	//though it says "discard" in the fxn, what it means is remove from playable hand. It does not go into the discard pile until another function tells it to.
	cardEffect(cutpurse,0,0,0,&G,handPos,&coin_bonus);
	playerTwoCoins = getPlayerTotal(&G,player+1);
	playerThreeCoins = getPlayerTotal(&G,player+2);

	if (
			(G.coins==(startingCoinCount +2))&&
			(playerTwoCoins==4 ) &&
			(playerThreeCoins==4 )

			)  
	{
		printf("Passed basic card test\n");
	}
	else{
		printf("Failed basic card test\n");
	}
	///////////////////////////////////////////////////////////////////////////////////////////////////////
	
	
	
	
	
	
	//Let's randomly assign coins for this test. Might as well do it a bunch of times too.
	///////////////////////////////////////////////////////////////////////////////////////////////////////
	srand(time(NULL));//seed the rand function to time (reseed it to the normal seed after this fxn)
	int z;
	int passedTest = 1;//bool for passed. We will switch this if it fails.  Innocent until proven guilty.'Murica.
	for (z=0; z<5000; z++) {
			
		
		initializeGame(numPlayer, k, seed, &G);
		coin_bonus=0;
		startingDeckCount = G.deckCount[player];
		startingHandCount = G.handCount[player];
		startingActionsCount = G.numActions;
		startingCoinCount = G.coins; //this gets updated each turn, so not associated to a particular player
		
		playerThreeCoins = 0;
		playerTwoCoins = 0;
		
		int y;
		for (x=0; x<5; x++) { //fill up player 2
			y = (rand() % 2);//we want 0,1,or2
			if (y == 0) {
				G.hand[player+1][x] = copper;

			}
			else if (y==1){
				G.hand[player+1][x] = silver;
			}
			else {
				G.hand[player+1][x] = gold;
			}
			
			G.handCount[player+1] +=1;
			
		}
		
		for (x=0; x<5; x++) { //fill up player 3, but allow for 0 coins as well (fairly likely chance)
			y = (rand() % 10);//we want 0,1,or2
			if (y == 0) {
				G.hand[player+2][x] = copper;
				
			}
			else if (y==1){
				G.hand[player+2][x] = silver;
			}
			else if (y==2){
				G.hand[player+2][x] = gold;
			}
			else {
				G.hand[player+2][x] = curse;//just a random card that has no coin value

			}

			G.handCount[player+2] +=1;
			
		}
		//printf("Player 3 has: %d coins\n", getPlayerTotal(&G,player+2));
		
		handPos = 0;
		
		//this card should add 2 coins to the gamestate during the turn. Also, it should remove one copper from any other player that has at least one copper.
		// Should be fun to test
		//though it says "discard" in the fxn, what it means is remove from playable hand. It does not go into the discard pile until another function tells it to.
		int startingPlayerTwoCoinCount = getPlayerTotal(&G,player+1); //count the coins
		int startingPlayerThreeCoinCount = getPlayerTotal(&G,player+2);
		int playerOneCopper = doesPlayerHaveCopper(&G,player+1); //make sure they have copper to give up to this card play
		int playerTwoCopper = doesPlayerHaveCopper(&G,player+2);
		int indtendedAdjustmentAmountTwo = 0;//we will use this to check against later
		int indtendedAdjustmentAmountThree = 0;

		if (playerOneCopper) {//if they have copper, the amount should be adjusted down by one
			indtendedAdjustmentAmountTwo = -1;
		}
		if (playerTwoCopper) {
			indtendedAdjustmentAmountThree = -1;

		}
		
		
		cardEffect(cutpurse,0,0,0,&G,handPos,&coin_bonus);
		playerTwoCoins = getPlayerTotal(&G,player+1);
		playerThreeCoins = getPlayerTotal(&G,player+2);
		
		
		
		if (
				(G.coins==(startingCoinCount +2))&&
				(playerTwoCoins== (startingPlayerTwoCoinCount + indtendedAdjustmentAmountTwo ))&&
				(playerThreeCoins== (startingPlayerThreeCoinCount + indtendedAdjustmentAmountThree ))

				)  
		{
			//printf("Passed random coins Test\n");
		}
		else{
			passedTest=0;//failed
			//printf("Failed random coins Test\n");
		}
	}
	
	
	//now we see if it ever failed, and print the response.
	if (passedTest==1) {
		printf("Passed random coins Test\n");
	}
	else {
		printf("Passed random coins Test\n");
	}

	
	
	srand(seed);//put this back how it was
	///////////////////////////////////////////////////////////////////////////////////////////////////////

	
	return 0;
}


//get the total number of coins for a given player that is in their hand
int getPlayerTotal(struct gameState * state, int playerNumber){
	//get total for player one
	int x;
	
	int total = 0;
	for (x=0; x<state->handCount[playerNumber]; x++) {
		if(state->hand[playerNumber][x] == copper){
			total+=1;
		}
		else if(state->hand[playerNumber][x] == silver){
			total+=2;
		}
		else if(state->hand[playerNumber][x] == gold){
			total+=3;
		}
	}
	return total;
}

int doesPlayerHaveCopper(struct gameState * state, int playerNumber){
	int x;
	for (x=0; x<state->handCount[playerNumber]; x++) {
		if(state->hand[playerNumber][x] == copper){
			return 1;
		}
	}
	
	return 0;//no copper was found
	
}

//	printf("Deck count before cardEffect: %d\n", G.deckCount[player]);
//	printf("Discard count before cardEffect: %d\n", G.discardCount[player]);
//	printf("Played count before cardEffect: %d\n", G.playedCardCount);
//	printf("Hand count before cardEffect: %d\n", G.handCount[player]);
//	
//	printf("Deck count after cardEffect: %d\n", G.deckCount[player]);
//	printf("Discard count after cardEffect: %d\n", G.discardCount[player]);
//	printf("Hand count after cardEffect: %d\n", G.handCount[player]);
//	printf("Played count after cardEffect: %d\n", G.playedCardCount);